package commons;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
 * 
 * Super-class of both Protocols
 * contains constants, and some facilitator methods
 *
 */
public abstract class OMGProtocol {
	public static final int NONE = -1;
	public static final int IDLE = 0; //idle state 
	public static final int CONNECTED = 1; //connected state 
	public static final int	LIST_REQUEST = 2; //requesting game list
	public static final int	JOINING_GAME = 3; 
	public static final int	PLAYING_GAME = 4;
	public static final int	PINGING = 5;
	public static final int CONNECTING = 6; 

	// 30 second ping time out
	protected static final int TIME_OUT = 30 * 1000;
	protected static final int PING_MAX = 2;

	protected int currentState;
	protected String servername;
	protected boolean waitingForResponse;
	protected long lastTimeLocal = 0;
	protected int lastTimeRemote = 0;
	protected Integer gameID;

	public void gotResponse() {
		this.waitingForResponse = false;
	}

	public int getState() {
		return currentState;
	}

	public String getStateDescription() {
		switch(currentState){
		case NONE:
			return "No state!";
		case IDLE:
			return "IDLE";
		case CONNECTED:
			return "CONNECTED";
		case LIST_REQUEST:
			return "LIST_REQUEST";
		case JOINING_GAME:
			return "JOINING_GAME";
		case PLAYING_GAME:
			return "PLAYING_GAME";
		case PINGING:
			return "PINGING";
		case CONNECTING:
			return "CONNECTING";
		default:
			return "ERROR";
		}
	}

	// Required DFA method
	abstract public Message runDFA(Message message) throws IOException, ClassNotFoundException;


	public Object deserialize(byte[] data) throws IOException, ClassNotFoundException {
		byte[] bytes = new byte[data.length];
		for(int i = 0; i < data.length; i++)
		{
			bytes[i] = (byte)data[i];
		}
		ByteArrayInputStream bi = new ByteArrayInputStream(bytes);
		ObjectInputStream  is = new ObjectInputStream(bi);

		Object object = is.readObject();

		is.close();
		return object;
	}

	public byte[] serialize(Object object) throws IOException {
		ByteArrayOutputStream bo = new ByteArrayOutputStream();

		ObjectOutputStream os = new ObjectOutputStream(bo);

		os.writeObject(object);
		os.flush();
		os.close();

		byte[] bytes = bo.toByteArray();
		char[] chars = new char[bytes.length];
		for(int i = 0; i < bytes.length; i++)
		{

			chars[i] = (char)bytes[i];
		}

		return bytes;
	}
}
